package com.cs171.market.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cs171.market.Repository.PermissionRepository;
import com.cs171.market.Repository.RoleRepository;
import com.cs171.market.entity.Permission;
import com.cs171.market.entity.Role;
import org.apache.commons.lang.enums.Enum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author yangyifei
 * @version 1.0
 * @date 2020/6/20 10:57
 */

@CrossOrigin
@RestController
public class RoleController {
    @Autowired
    private PermissionRepository permissionRepository;
    @Autowired
    private RoleRepository roleRepository;

    /**
     * 1.查询全部的角色列表
     * @return 多条数据
     */
    @GetMapping("/roles")
    public Object getRoleLists(){
        JSONObject result = jsonhead();
        List<Permission> data = permissionRepository.findAll();
        List<Role> roleList = roleRepository.findAll();
        for(Role r : roleList){
            // 1.准备每个角色的权限id列表
            String tmp = r.getrList();
            if(tmp == null) continue;
            String[] pidList = tmp.split(",");
            List<Integer> pids = new ArrayList<>();
            for(String s : pidList){
                pids.add(Integer.valueOf(s));
            }
            // 2.遍历权限树所有的权限，只拿该角色id的权限，组成树形结构,存在re_children中
            List<Permission> re_children = new ArrayList<>();
            //先找到所有0级分类
            for(Permission p : data){
                if(p.getPpid() == 0 && pids.contains(p.getPid())){
                    re_children.add(p);
                }
            }
            // 为0级分类添加子菜单，getChildren1是递归调用的
            for(Permission p : re_children){
                p.setPermissionList(getChildren2(p.getPid(), data, pids));
            }

            // 3.添加成json返回给前端
            r.setPermissionList(re_children);
        }

        // 输出
        JSONArray rArray = (JSONArray) JSON.toJSON(roleList);
        result.put("data", rArray);

        return result;
    }

    /**
     * 2.添加角色
     * @return 一个角色
     */
    @PostMapping("roles")
    public Object roleAdd(@ModelAttribute("roleName") String roleName, @ModelAttribute("roleDesc") String roleDesc) {
        JSONObject result = jsonhead();
        Role role = new Role(roleName, roleDesc);
        Role newRole = roleRepository.save(role);
        JSONObject roleJson = (JSONObject) JSON.toJSON(role);
        result.put("data", roleJson);
        result.getJSONObject("meta").put("msg","创建成功");
        return result;
    }

    /**
     * 3.根据id查询角色
     * @return 一条数据
     */
    @GetMapping("/roles/{id}")
    public Object getRoleLists(@PathVariable("id") Integer rid){
        JSONObject result = jsonhead();
        Role role = roleRepository.findById(rid).orElse(null);
        List<Permission> data = permissionRepository.findAll();
        String tmp = role.getrList();
        if(tmp == null) return result;
        String[] pidList = tmp.split(",");
        List<Integer> pids = new ArrayList<>();
        for(String s : pidList){
            pids.add(Integer.valueOf(s));
        }
        // 2.遍历权限树所有的权限，只拿该角色id的权限，组成树形结构,存在re_children中
        List<Permission> re_children = new ArrayList<>();
        //先找到所有0级分类
        for(Permission p : data){
            if(p.getPpid() == 0 && pids.contains(p.getPid())){
                re_children.add(p);
            }
        }
        // 为0级分类添加子菜单，getChildren1是递归调用的
        for(Permission p : re_children){
            p.setPermissionList(getChildren2(p.getPid(), data, pids));
        }

        // 3.添加成json返回给前端
        role.setPermissionList(re_children);

        // 输出
        JSONObject roleJson = (JSONObject) JSON.toJSON(role);
        result.put("data", roleJson);
        return result;
    }

    /**
     * 4.编辑提交角色
     * @return 一条数据
     */
    @PutMapping("roles/{roleid}")
    /* @ModelAttribute注解在方法参数上时，如果参数类型没有无参构造函数，那这个参数是必填的，
    当有无参构成函数，参数是非必填的。所以一般基础数字对象类型都会报错，比如Long型, 但String不会
    @ModelAttribute一定要指明参数名，当参数类型是一个bean的时候，它可以按照bean的属性一一注入。*/
    public Object rechangeRole(@PathVariable("roleid") Integer rid,
                               @ModelAttribute("roleName") String roleName,
                               @ModelAttribute("roleDesc") String roleDesc){
        JSONObject result = jsonhead();
        Role oldRole = roleRepository.findById(rid).orElse(null);
        if(oldRole == null) return result;
        else{
            oldRole.setRole(roleName);
            String newRoleDesc = (roleDesc == null)? oldRole.getRdesc():roleDesc;
            oldRole.setRdesc(newRoleDesc);
            roleRepository.save(oldRole);
        }
        JSONObject roleJson = (JSONObject) JSON.toJSON(oldRole);
        result.put("data", roleJson);
        result.getJSONObject("meta").put("msg","更新成功");
        return result;

    }

    /**
     * 5.删除角色
     * @return data:null
     */
    @DeleteMapping("roles/{roleid}")
    public Object roleDelete(@PathVariable("roleid") Integer rid){
        JSONObject result = jsondelete();
        result.getJSONObject("meta").put("msg","删除成功");
        roleRepository.delete(roleRepository.findById(rid).orElse(null));
        return result;
    }

    /**
     * 6.角色授权
     * @return data:null
     */
    @PostMapping("roles/{roleid}/rights")
    public Object roleAuthentication(@PathVariable("roleid") Integer rid, @ModelAttribute("rids") String pids){
        JSONObject result = jsondelete();
        if(pids == null) return result;
        else{
            Role role = roleRepository.findById(rid).orElse(null);
            if(role == null) return result;
            else{
                if(pids != null && !pids.equals("")){
                    role.setrList(role.getrList()+","+pids);
                    roleRepository.save(role);
                }

            }
        }
        return result;
    }

    /**
     * 7.删除角色指定权限
     * @return 当前角色下最新的权限数据
     */
    @DeleteMapping("roles/{roleid}/rights/{rightid}")
    public Object roleDeleteAuthentication(@PathVariable("roleid") Integer rid, @PathVariable("rightid") String pid){
        JSONObject result = jsonhead();
        Role role = roleRepository.findById(rid).orElse(null);
        Role newRole;
        String newPids = "";
        if(role == null) return result;
        else{
            String oldPids = role.getrList();
            if(oldPids.contains(pid)){
                Integer idx = oldPids.indexOf(pid);
                newPids = oldPids.substring(0, idx);
                newPids += oldPids.substring(idx+pid.length());
                newPids = newPids.replace(",,",",");
                if(newPids.charAt(newPids.length()-1) == ',')
                    newPids = newPids.substring(0,newPids.length()-1);
                System.out.println(newPids);
            }
            role.setrList(newPids);
            newRole = roleRepository.save(role);
        }

        List<Permission> data = permissionRepository.findAll();
        String tmp = newPids;
        if(tmp == null) return jsondelete();
        String[] pidList = tmp.split(",");
        List<Integer> pids = new ArrayList<>();
        for(String s : pidList){
            pids.add(Integer.valueOf(s));
        }
        // 2.遍历权限树所有的权限，只拿该角色id的权限，组成树形结构,存在re_children中
        List<Permission> re_children = new ArrayList<>();
        //先找到所有0级分类
        for(Permission p : data){
            if(p.getPpid() == 0 && pids.contains(p.getPid())){
                re_children.add(p);
            }
        }
        // 为0级分类添加子菜单，getChildren1是递归调用的
        for(Permission p : re_children){
            p.setPermissionList(getChildren2(p.getPid(), data, pids));
        }

        // 3.添加成json返回给前端
        newRole.setPermissionList(re_children);

        // 输出
        JSONArray arrayJson = (JSONArray) JSON.toJSON(re_children);
        result.put("data", arrayJson);
        result.getJSONObject("meta").put("msg","取消权限成功");
        return result;
    }

    /**
     * 递归查找子菜单
     *
     * @param id 当前权限id
     * @param rootList 要查找的列表
     * @return
     */
    private List<Permission> getChildren2(Integer id, List<Permission> rootList, List<Integer> pids){
        //子菜单
        List<Permission> childList = new ArrayList<>();
        for(Permission p : rootList){
            // 遍历所有节点，将父菜单id与传过来的id比较
            if(p.getPpid().equals(id) && pids.contains(p.getPid())){
                childList.add(p);
            }
        }
        // 把子菜单的子菜单再循环一遍
        for(Permission p : childList){
            p.setPermissionList(getChildren2(p.getPid(), rootList, pids));
        }
        // 递归退出条件
        if (childList.size() == 0){
            return null;
        }
        return childList;
    }

    /**
     * 重构代码，相似的Json Head
     * @return JsonObject
     */
    private JSONObject jsonhead(){
        JSONObject pAll = new JSONObject();
        JSONObject pSuccess = new JSONObject();
        pSuccess.put("msg", "获取角色列表成功");
        pSuccess.put("status", "200");
        pAll.put("meta", pSuccess);
        return pAll;
    }

    /**
     * 重构代码，相似的Json delete
     * @return JsonObject
     */
    private JSONObject jsondelete(){
        JSONObject pAll = new JSONObject();
        JSONObject pSuccess = new JSONObject();
        pSuccess.put("msg", "更新成功");
        pSuccess.put("status", "200");
        pAll.put("meta", pSuccess);
        pAll.put("data", "null");
        return pAll;
    }
}
